using Domain;
using Domain.BOM;
using Domain.Quality;
using Domain.RBAC;
using Domain.Warehousies;
using Domain.工艺工序;
using Domain.生产订单;
using Infratructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog.Web;
using SqlSugar;
using System.Reflection;
using System.Text;
using Team.API;
using Team.API.Hubs;
using Team.API.Services;
using Yitter.IdGenerator;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();

// 注册SignalR
builder.Services.AddSignalR();

// 注册设备状态服务（共享逻辑）
builder.Services.AddScoped<IEquipmentStatusService, EquipmentStatusService>();

// 注册后台服务（设备状态定时检查，每分钟执行一次）

builder.Services.AddHostedService<EquipmentStatusBackgroundService>();

// 注册后台服务（生产计划定时推送，每分钟执行一次）
builder.Services.AddHostedService<ProductionScheduleBackgroundService>();

// 注册后台服务（自动创建订单，每小时执行一次）
builder.Services.AddHostedService<AutoCreateOrderBackgroundService>();

// 注册后台服务（自动排程，每2分钟执行一次）
builder.Services.AddHostedService<AutoSchedulingBackgroundService>();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddSwaggerGen(o =>
{
    o.IncludeXmlComments(AppContext.BaseDirectory + "Team.API.xml", true);//接口注释
    // 显示 授权信息
    o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
    {
        Description = "添加JWT授权Token：Bearer Token值",
        Name = "Authorization",
        In = Microsoft.OpenApi.Models.ParameterLocation.Header,
        Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
    o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[]
            {
            }
        }
    });
});
#region sqlsuger
var connstr = builder.Configuration["ConnectionStrings:conn"];
//创建数据库对象 (用法和EF Dappper一样通过new保证线程安全)
//SqlSugarClient Db = new SqlSugarClient(new ConnectionConfig()
//{
//    ConnectionString = connstr,
//    DbType = DbType.MySql,
//    IsAutoCloseConnection = true
//});
#endregion
//注册上下文：AOP里面可以获取IOC对象，如果有现成框架比如Furion可以不写这一行
builder.Services.AddHttpContextAccessor();
//注册SqlSugar用AddScoped
builder.Services.AddScoped<ISqlSugarClient>(s =>
{
    //Scoped用SqlSugarClient 
    SqlSugarClient sqlSugar = new SqlSugarClient(new ConnectionConfig()
    {
        ConnectionString = connstr,
        DbType = DbType.MySql,
        IsAutoCloseConnection = true,
        MoreSettings = new ConnMoreSettings()   //在实体删除属性
        {
            //只支持.net core

            SqliteCodeFirstEnableDropColumn = true
        }
    },
   db =>
   {
       //每次上下文都会执行

       //获取IOC对象不要求在一个上下文
       //var log=s.GetService<Log>()

       //获取IOC对象要求在一个上下文
       //var appServive = s.GetService<IHttpContextAccessor>();
       //var log= appServive?.HttpContext?.RequestServices.GetService<Log>();

       db.Aop.OnLogExecuting = (sql, pars) =>
       {
       };
   });
    //建库：如果不存在创建数据库存在不会重复创建 createdb
    // sqlSugar.DbMaintenance.CreateDatabase("teamWorkDB"); // 注意 ：Oracle和个别国产库需不支持该方法，需要手动建库 
    /***手动建多个表***/
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Nlogmodel, Usermodel, Rolemodel, Permissionmodel, Departmentmodel>();
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Rolepermissionmiddle, Bomtable, Dictionarymodel, Makestepmodel, Productionschedulemodel>();
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Warehousemodel, Outboundmodel, Inboundmodel, Warehousecheckmodel, Inventorylocationmodel>();
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Waregoodsmodel, Batchmdoel, Lanewaymodel, Palletmodel>();
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Qualitymodel, Equipmentmodel, Workmodel>();
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<OrderModel>();  //生产订单实体迁移
    return sqlSugar;
});
#region 其他注册
//注册中介者
builder.Services.AddMediatR(x => x.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
//注册Automapper
builder.Services.AddAutoMapper(typeof(AutomapperFiles));
//注册仓储
builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
//注册雪花Id
YitIdHelper.SetIdGenerator(new IdGeneratorOptions());
//注册日志
builder.Host.UseNLog();
//注册全局redis缓存
var redis = new CSRedis.CSRedisClient(builder.Configuration["Redisconnstr:redisstr"]);  //定义redis实例
builder.Services.AddSingleton(redis);  //Redis设为全局单例模式
//授权认证（使用JWT）
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
{
    // 私钥
    var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
    o.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        // 验证发布者
        ValidateIssuer = true,
        // 发布者信息
        ValidIssuer = "BeiJingBW",

        // 验证接收者
        ValidateAudience = true,
        // 接收者
        ValidAudience = "BeiJingBW",

        // 验证是否过期
        ValidateLifetime = true,

        // 验证私钥
        IssuerSigningKey = new SymmetricSecurityKey(secretByte)

    };
});
#endregion
// 配置CORS（支持SignalR）
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
    {
        policy.WithOrigins("http://localhost:5173", "http://localhost:5174", "http://152.136.201.158:8088")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // SignalR需要允许凭据
    });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
{
    app.UseSwagger();

    app.UseSwaggerUI();
}

app.UseCors("AllowFrontend");  //允许跨域（支持SignalR）


app.UseStaticFiles();  //允许静态文件

app.UseAuthentication(); // 鉴权

app.UseAuthorization();

// 映射SignalR Hub
app.MapHub<EquipmentStatusHub>("/equipmentStatusHub");

app.MapControllers();
// 👇 手动触发一次 SqlSugar 初始化（确保建表）
using (var scope = app.Services.CreateScope())
{
    var sqlSugar = scope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
    // 这里你可以再调用一次 InitTables，确保执行
    sqlSugar.CodeFirst.SetStringDefaultLength(200).InitTables<Productionschedulemodel>();
}
app.Run();